import { InjectQueue, Process, Processor } from "@nestjs/bull";
import {
  BadRequestException,
  Injectable,
  InternalServerErrorException,
} from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Job, Queue } from "bull";
import { getConnection, Repository } from "typeorm";
import { ReceivedGoodsDto } from "../../adminModule/operate/dto/order.dto";
import {} from "../dto/goods.dto";
import {
  AddOrderDto,
  GetOrderByIdDto,
  GetOrderByStatusDto,
  PayOrderDto,
} from "../dto/order.dto";
import { Goods } from "/@/entities/goods/Goods.entity";
import { Cart } from "/@/entities/operate/Cart.entity";
import { Order } from "/@/entities/order/Order.entity";
import { OrderEnum } from "/@/enum/order.enum";
import { RangeEnum } from "/@/enum/range.enum";
import { format } from "/@/utils/moment";
@Injectable()
@Processor("task")
export class WeappOrderService {
  constructor(
    @InjectQueue("task") private readonly taskQueue: Queue,
    @InjectRepository(Goods)
    private goodsRepository: Repository<Goods>,
    @InjectRepository(Order)
    private orderRepository: Repository<Order>,
    @InjectRepository(Cart)
    private cartRepository: Repository<Cart>,
  ) {
    //
  }

  /**
   * 任务队列消费者，处理订单过期
   * @param params 字段
   */
  @Process("checkOrder")
  async processTask(job: Job<any>) {
    const { id } = job.data;
    const order = await this.orderRepository.findOne({ id });
    // 如果订单还是待支付状态 则直接取消订单
    if (order.status === OrderEnum.PAID) {
      await this.orderRepository.update(id, { status: OrderEnum.CANCEL });
      console.log(`订单${id}已被取消`);
    }
  }

  /**
   * 获取订单 根据id
   * @param query 字段
   */
  async getOrderById(query: GetOrderByIdDto) {
    try {
      const { id } = query;
      const order = await this.orderRepository.findOne(id, {
        relations: ["carts"],
      });

      for (let i = 0; i < order.carts.length; i++) {
        order.carts[i].goods = await this.goodsRepository.findOne({
          id: parseInt(order.carts[i].goods_id),
        });
      }
      order.create_at = format(order.create_at, "YYYY-MM-DD HH:mm:ss");
      return order;
    } catch (error) {
      throw new InternalServerErrorException("查询失败");
    }
  }

  /**
   * 获取订单 根据status
   * @param query 字段
   */
  async getOrderByStatus(query: GetOrderByStatusDto) {
    try {
      const { status } = query;
      let qb = this.orderRepository.createQueryBuilder("order");
      qb = qb
        .orderBy("order.update_at", "DESC")
        .where("order.status = :status", { status });
      const [items, total] = await qb.getManyAndCount();
      items.map((item) => {
        item.create_at = format(item.create_at, "YYYY-MM-DD HH:mm:ss");
        return item;
      });
      return { items, total };
    } catch (error) {
      throw new InternalServerErrorException("查询失败");
    }
  }

  /**
   * 添加订单
   * @param params 字段
   */
  async addOrder(params: AddOrderDto, user: any) {
    try {
      const { carts } = params;
      params.user_id = user.id;
      delete params.carts;
      const connection = getConnection();
      const followList = [];
      // 为订单和购物车表关联
      for (let i = 0; i < carts.length; i++) {
        const goods = await connection.manager.findOne(Cart, {
          id: carts[i],
        });
        if (!goods) {
          throw new InternalServerErrorException("购物车添加到订单操作失败");
        }
        followList.push(goods);
      }
      const entity = this.orderRepository.create(params);

      entity.carts = followList;
      // 保存数据
      const result = await connection.manager.save(entity);

      // 如果下单成功，
      if (result) {
        // 则修改购物车的状态，在客户端不在显示
        for (let i = 0; i < carts.length; i++) {
          await this.cartRepository.update(carts[i], { status: "2" });
        }
        // 创建订单，超时取消订单
        await this.taskQueue.add(
          "checkOrder",
          { id: result.id },
          { delay: RangeEnum.ORDER_OVER_TIME },
        );
      }
      return result;
    } catch (error) {
      console.log(error);
      throw new InternalServerErrorException("添加失败");
    }
  }

  /**
   * 用户支付订单
   * @param params 字段
   */
  async payOrder(param: PayOrderDto, user: any) {
    try {
      const { id } = param;
      const { id: user_id } = user;
      const order = await this.orderRepository.findOne({ id, user_id });
      if (!order) {
        throw new BadRequestException("订单号有误");
      }
      if (order.status !== "1") {
        throw new BadRequestException("订单已失效");
      }
      order.status = OrderEnum.SHIPPED;
      await this.orderRepository.update(id, order);
    } catch (error) {
      console.log(error);
      throw new InternalServerErrorException(error.response || "操作失败");
    }
  }

  /**
   * 标记收货，完成订单
   * @param params 字段
   */
  async receivedGoods(params: PayOrderDto, user: any) {
    const { id } = params;
    const { id: user_id } = user;
    const swiper = await this.orderRepository.findOne({ id, user_id });
    if (!swiper) {
      throw new BadRequestException("查无此订单");
    }
    if (swiper.status !== OrderEnum.RECEIVED) {
      throw new BadRequestException("订单状态有误");
    }
    await this.orderRepository.update(id, { status: OrderEnum.FINISH });
    return "ok";
  }
}
